// --------------------------------------------------------------------------------------------------------------------- 
// <copyright file="T4PropertyCollector.cs" company="Microsoft.Blueprints.Contrib Team">
//   (C) 2009 Microsoft.Blueprints.Contrib Team
// </copyright>
// <summary>
//   Defines the T4PropertyCollector type.
// </summary>
// ---------------------------------------------------------------------------------------------------------------------

namespace Microsoft.Blueprints.Contrib.T4
{
    #region Using Directives

    using System.Collections.Generic;
    using System.Linq;

    using Microsoft.SoftwareFactories.Blueprints;

    #endregion

    /// <summary>
    /// Extracts the properties from any T4 template added to this Builder object.
    /// Returns a unified list of all properties discovered.
    /// </summary>
    public class T4PropertyCollector
    {
        /// <summary>
        /// Dictionary which contains the properties and data exposed by the T4 Template
        /// </summary>
        private readonly Dictionary<string, T4PropertyData> properties = new Dictionary<string, T4PropertyData>();

        /// <summary>
        /// Internal collection of T4 Templates
        /// </summary>
        private readonly T4Templates templates = new T4Templates();

        /// <summary>
        /// Initialises the T4PropertyCollector
        /// </summary>
        /// <returns>
        /// A new instance of the T4PropertyCollector
        /// </returns>
        public static T4PropertyCollector Start()
        {
            return new T4PropertyCollector();
        }

        /// <summary>
        /// Add a template to be parsed for properties.
        /// </summary>
        /// <param name="fileName">
        /// The file name.
        /// </param>
        /// <returns>
        /// An instance of the T4PropertyCollector
        /// </returns>
        public T4PropertyCollector AddTemplate(string fileName)
        {
            this.templates.Add(new T4Template { ContentFilePath = fileName });

            return this;
        }

        /// <summary>
        /// Parses all the loaded templates to extract a unified list of
        /// T4 properties.
        /// </summary>
        /// <returns>
        /// An instance of the T4PropertyCollector
        /// </returns>
        public T4PropertyCollector Collect()
        {
            this.templates.ForEach(t => t.PopulateProperties());
            var result = this.templates.Select(t => t.Properties);

            foreach (Dictionary<string, T4PropertyData> dictionary in result)
            {
                foreach (KeyValuePair<string, T4PropertyData> pair in dictionary)
                {
                    if (!this.properties.ContainsKey(pair.Key))
                    {
                        this.properties.Add(pair.Key, pair.Value);
                    }
                }
            }

            return this;
        }

        /// <summary>
        /// Call to end the Build process and return the populated property dictionary.
        /// </summary>
        /// <returns>
        /// A dictionary containing all discovered properties.
        /// </returns>
        public Dictionary<string, T4PropertyData> Finish()
        {
            return this.properties;
        }
    }
}